﻿using System;
using System.Reflection;

namespace Aeon.Emulator.Decoding
{
    /// <summary>
    /// Contains information for members used via reflection.
    /// </summary>
    internal static class Infos
    {
        /// <summary>
        /// Contains information for Processor members used via reflection.
        /// </summary>
        public static class Processor
        {
            #region Fields
            public static readonly FieldInfo PAX = typeof(Aeon.Emulator.Processor).GetField("PAX", BindingFlags.Instance | BindingFlags.NonPublic);
            public static readonly FieldInfo PBX = typeof(Aeon.Emulator.Processor).GetField("PBX", BindingFlags.Instance | BindingFlags.NonPublic);
            public static readonly FieldInfo PCX = typeof(Aeon.Emulator.Processor).GetField("PCX", BindingFlags.Instance | BindingFlags.NonPublic);
            public static readonly FieldInfo PDX = typeof(Aeon.Emulator.Processor).GetField("PDX", BindingFlags.Instance | BindingFlags.NonPublic);

            public static readonly FieldInfo PAH = typeof(Aeon.Emulator.Processor).GetField("PAH", BindingFlags.Instance | BindingFlags.NonPublic);
            public static readonly FieldInfo PBH = typeof(Aeon.Emulator.Processor).GetField("PBH", BindingFlags.Instance | BindingFlags.NonPublic);
            public static readonly FieldInfo PCH = typeof(Aeon.Emulator.Processor).GetField("PCH", BindingFlags.Instance | BindingFlags.NonPublic);
            public static readonly FieldInfo PDH = typeof(Aeon.Emulator.Processor).GetField("PDH", BindingFlags.Instance | BindingFlags.NonPublic);

            public static readonly FieldInfo PBP = typeof(Aeon.Emulator.Processor).GetField("PBP", BindingFlags.Instance | BindingFlags.NonPublic);
            public static readonly FieldInfo PSI = typeof(Aeon.Emulator.Processor).GetField("PSI", BindingFlags.Instance | BindingFlags.NonPublic);
            public static readonly FieldInfo PDI = typeof(Aeon.Emulator.Processor).GetField("PDI", BindingFlags.Instance | BindingFlags.NonPublic);
            public static readonly FieldInfo PSP = typeof(Aeon.Emulator.Processor).GetField("PSP", BindingFlags.Instance | BindingFlags.NonPublic);

            public static readonly FieldInfo PIP = typeof(Aeon.Emulator.Processor).GetField("PIP", BindingFlags.Instance | BindingFlags.NonPublic);

            public static readonly PropertyInfo CSBase = typeof(Aeon.Emulator.Processor).GetProperty("CSBase", BindingFlags.Instance | BindingFlags.Public);

            public static readonly FieldInfo FPU = typeof(Aeon.Emulator.Processor).GetField("FPU", BindingFlags.Instance | BindingFlags.Public);

            public static readonly FieldInfo CachedIP = typeof(Aeon.Emulator.Processor).GetField("CachedIP", BindingFlags.Instance | BindingFlags.NonPublic);
            public static readonly FieldInfo CachedInstruction = typeof(Aeon.Emulator.Processor).GetField("CachedInstruction", BindingFlags.Instance | BindingFlags.NonPublic);
            public static readonly FieldInfo StartEIP = typeof(Aeon.Emulator.Processor).GetField("StartEIP", BindingFlags.Instance | BindingFlags.NonPublic);

            public static readonly FieldInfo BaseOverrides = typeof(Aeon.Emulator.Processor).GetField("baseOverrides", BindingFlags.Instance | BindingFlags.NonPublic);
            public static readonly FieldInfo DefaultSegments16 = typeof(Aeon.Emulator.Processor).GetField("defaultSegments16", BindingFlags.Instance | BindingFlags.NonPublic);
            public static readonly FieldInfo DefaultSibSegments32Mod12 = typeof(Aeon.Emulator.Processor).GetField("defaultSibSegments32Mod12", BindingFlags.Instance | BindingFlags.NonPublic);
            public static readonly FieldInfo SegmentBases = typeof(Aeon.Emulator.Processor).GetField("segmentBases", BindingFlags.Instance | BindingFlags.NonPublic);
            public static readonly FieldInfo SegmentOverride = typeof(Aeon.Emulator.Processor).GetField("SegmentOverride", BindingFlags.Instance | BindingFlags.Public);
            public static readonly FieldInfo Flags = typeof(Aeon.Emulator.Processor).GetField("Flags", BindingFlags.Instance | BindingFlags.Public);
            public static readonly FieldInfo SizeOverride = typeof(Aeon.Emulator.Processor).GetField("SizeOverride", BindingFlags.Instance | BindingFlags.NonPublic);
            public static readonly FieldInfo RepeatPrefix = typeof(Aeon.Emulator.Processor).GetField("RepeatPrefix", BindingFlags.Instance | BindingFlags.Public);
            public static readonly FieldInfo PrefixCount = typeof(Aeon.Emulator.Processor).GetField("PrefixCount", BindingFlags.Instance | BindingFlags.NonPublic);
            public static readonly FieldInfo TemporaryInterruptMask = typeof(Aeon.Emulator.Processor).GetField("TemporaryInterruptMask", BindingFlags.Instance | BindingFlags.NonPublic);
            #endregion

            #region Properties
            public static readonly PropertyInfo SizeModeIndex = typeof(Aeon.Emulator.Processor).GetProperty("SizeModeIndex", BindingFlags.Instance | BindingFlags.NonPublic);
            #endregion

            #region Methods
            public static readonly MethodInfo InstructionEpilog = typeof(Aeon.Emulator.Processor).GetMethod("InstructionEpilog", BindingFlags.Instance | BindingFlags.NonPublic);
            public static readonly MethodInfo GetSegmentRegisterPointer = typeof(Aeon.Emulator.Processor).GetMethod("GetSegmentRegisterPointer", BindingFlags.Instance | BindingFlags.NonPublic);
            public static readonly MethodInfo GetRegisterWordPointer = typeof(Aeon.Emulator.Processor).GetMethod("GetRegisterWordPointer", BindingFlags.Instance | BindingFlags.NonPublic);
            public static readonly MethodInfo GetRegisterBytePointer = typeof(Aeon.Emulator.Processor).GetMethod("GetRegisterBytePointer", BindingFlags.Instance | BindingFlags.NonPublic);
            public static readonly MethodInfo GetOverrideSegment = typeof(Aeon.Emulator.Processor).GetMethod("GetOverrideSegment", BindingFlags.Instance | BindingFlags.NonPublic);
            public static readonly MethodInfo GetDebugRegisterPointer = typeof(Aeon.Emulator.Processor).GetMethod("GetDebugRegisterPointer", BindingFlags.Instance | BindingFlags.NonPublic);
            public static readonly MethodInfo GetOverrideBase = typeof(Aeon.Emulator.Processor).GetMethod("GetOverrideBase", BindingFlags.Instance | BindingFlags.NonPublic);
            #endregion
        }

        public static class FPU
        {
            #region Methods
            public static readonly MethodInfo GetRegisterValue = typeof(Aeon.Emulator.FPU).GetMethod("GetRegisterValue", BindingFlags.Instance | BindingFlags.Public);
            #endregion
        }

        /// <summary>
        /// Contains information for VirtualMachine members used via reflection.
        /// </summary>
        public static class VirtualMachine
        {
            #region Fields
            public static readonly FieldInfo Processor = typeof(Aeon.Emulator.VirtualMachine).GetField("Processor", BindingFlags.Instance | BindingFlags.Public);
            public static readonly FieldInfo PhysicalMemory = typeof(Aeon.Emulator.VirtualMachine).GetField("PhysicalMemory", BindingFlags.Instance | BindingFlags.Public);
            #endregion

            #region Methods
            public static readonly MethodInfo WriteSegmentRegister = typeof(Aeon.Emulator.VirtualMachine).GetMethod("WriteSegmentRegister", BindingFlags.Instance | BindingFlags.Public);
            public static readonly MethodInfo UpdateSegment = typeof(Aeon.Emulator.VirtualMachine).GetMethod("UpdateSegment", BindingFlags.Instance | BindingFlags.NonPublic);
            #endregion
        }

        /// <summary>
        /// Contains information for PhysicalMemory members used via reflection.
        /// </summary>
        public static class PhysicalMemory
        {
            #region Fields
            public static readonly FieldInfo RawView = typeof(Aeon.Emulator.PhysicalMemory).GetField("RawView", BindingFlags.Instance | BindingFlags.NonPublic);
            #endregion

            #region Methods
            public static readonly MethodInfo GetByte = typeof(Aeon.Emulator.PhysicalMemory).GetMethod("GetByte", new Type[] { typeof(uint) });
            public static readonly MethodInfo SetByte = typeof(Aeon.Emulator.PhysicalMemory).GetMethod("SetByte", new Type[] { typeof(uint), typeof(byte) });

            public static readonly MethodInfo GetUInt16 = typeof(Aeon.Emulator.PhysicalMemory).GetMethod("GetUInt16", new Type[] { typeof(uint) });
            public static readonly MethodInfo SetUInt16 = typeof(Aeon.Emulator.PhysicalMemory).GetMethod("SetUInt16", new Type[] { typeof(uint), typeof(ushort) });

            public static readonly MethodInfo GetUInt32 = typeof(Aeon.Emulator.PhysicalMemory).GetMethod("GetUInt32", new Type[] { typeof(uint) });
            public static readonly MethodInfo SetUInt32 = typeof(Aeon.Emulator.PhysicalMemory).GetMethod("SetUInt32", new Type[] { typeof(uint), typeof(uint) });

            public static readonly MethodInfo GetUInt64 = typeof(Aeon.Emulator.PhysicalMemory).GetMethod("GetUInt64", new Type[] { typeof(uint) });
            public static readonly MethodInfo SetUInt64 = typeof(Aeon.Emulator.PhysicalMemory).GetMethod("SetUInt64", new Type[] { typeof(uint), typeof(ulong) });

            public static readonly MethodInfo GetReal32 = typeof(Aeon.Emulator.PhysicalMemory).GetMethod("GetReal32", new Type[] { typeof(uint) });
            public static readonly MethodInfo SetReal32 = typeof(Aeon.Emulator.PhysicalMemory).GetMethod("SetReal32", new Type[] { typeof(uint), typeof(float) });

            public static readonly MethodInfo GetReal64 = typeof(Aeon.Emulator.PhysicalMemory).GetMethod("GetReal64", new Type[] { typeof(uint) });
            public static readonly MethodInfo SetReal64 = typeof(Aeon.Emulator.PhysicalMemory).GetMethod("SetReal64", new Type[] { typeof(uint), typeof(double) });

            public static readonly MethodInfo GetReal80 = typeof(Aeon.Emulator.PhysicalMemory).GetMethod("GetReal80", new Type[] { typeof(uint) });
            public static readonly MethodInfo SetReal80 = typeof(Aeon.Emulator.PhysicalMemory).GetMethod("SetReal80", new Type[] { typeof(uint), typeof(Real10) });

            public static readonly MethodInfo FetchInstruction = typeof(Aeon.Emulator.PhysicalMemory).GetMethod("FetchInstruction", BindingFlags.Instance | BindingFlags.NonPublic);
            #endregion
        }

        /// <summary>
        /// Contains information for RunimeCalls members used via reflection.
        /// </summary>
        public static class RuntimeCalls
        {
            #region Methods
            public static readonly MethodInfo NewLoadSibMod0Address = typeof(Aeon.Emulator.Decoding.RuntimeCalls).GetMethod("NewLoadSibMod0Address");
            public static readonly MethodInfo NewLoadSibMod12Address = typeof(Aeon.Emulator.Decoding.RuntimeCalls).GetMethod("NewLoadSibMod12Address");
            public static readonly MethodInfo NewLoadSibMod0Offset = typeof(Aeon.Emulator.Decoding.RuntimeCalls).GetMethod("NewLoadSibMod0Offset");
            public static readonly MethodInfo NewLoadSibMod12Offset = typeof(Aeon.Emulator.Decoding.RuntimeCalls).GetMethod("NewLoadSibMod12Offset");
            public static readonly MethodInfo GetMoffsAddress32 = typeof(Aeon.Emulator.Decoding.RuntimeCalls).GetMethod("GetMoffsAddress32", BindingFlags.Static | BindingFlags.Public);
            public static readonly MethodInfo GetModRMAddress32 = typeof(Aeon.Emulator.Decoding.RuntimeCalls).GetMethod("GetModRMAddress32", BindingFlags.Static | BindingFlags.Public);
            public static readonly MethodInfo ThrowException = typeof(Aeon.Emulator.Decoding.RuntimeCalls).GetMethod("ThrowException", BindingFlags.Static | BindingFlags.Public);
            #endregion
        }
    }
}
